package com.shenyutao.customimagecrop.test

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.View
import com.shenyutao.customimagecrop.R

/**
 * @author ShenYuTao
 */
class CustomView : View {
    private var mMatrix = Matrix()
    private lateinit var mPaint: Paint
    private lateinit var mClipRectPaint: Paint
    private lateinit var mTextPaint: Paint
    private lateinit var mPointPaint: Paint
    private lateinit var mLinePaint: Paint
    private lateinit var mRectPaint: Paint
    private lateinit var testPaint: Paint
    private lateinit var mCirclePaint: Paint
    private lateinit var mOvalPaint: Paint
    private lateinit var mArcPaint: Paint
    private lateinit var mPathPaint: Paint
    private lateinit var mBitmapPaint: Paint

    constructor(context: Context) : super(context) {
        init(null, 0)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init(attrs, 0)
    }

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(
        context,
        attrs,
        defStyle
    ) {
        init(attrs, defStyle)
    }

    fun Bitmap.setName(name: String) {
    }

    private lateinit var mBitmap: Bitmap

    private fun init(attrs: AttributeSet?, defStyle: Int) {
        testPaint = Paint()
        mTextPaint = Paint()
        mPointPaint = Paint()
        mLinePaint = Paint()
        mRectPaint = Paint()
        mCirclePaint = Paint()
        mOvalPaint = Paint()
        mArcPaint = Paint()
        mPathPaint = Paint()
        mBitmapPaint = Paint()

        mPaint = Paint()
        mPaint.isAntiAlias = true
        mPaint.isFilterBitmap = true

        //设置裁剪框画笔
        mClipRectPaint = Paint()
        mClipRectPaint.color = Color.parseColor("#AAFFFFFF")
        mClipRectPaint.strokeWidth = 6f

    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        mBitmap = findBitmap()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
//        canvas.drawBitmap(mBitmap, mMatrix, mPaint)
        drawArgb(canvas)
//        drawAxis(canvas)
//        drawText(canvas)
//        drawPoint(canvas)
//        drawLine(canvas)
//        drawRect(canvas)
//        drawCircle(canvas)
//        drawOval(canvas)
//        drawArc(canvas)
//        drawPath(canvas)
//        drawBitmap(canvas)
        testDraw(canvas)

    }

    private fun testDraw(canvas: Canvas){
        mRectPaint.color = Color.RED
        val rect1 = Rect(100,100,200,200)
        canvas.drawRect(rect1,mRectPaint)
        canvas.scale(0.5f,0.5f)
        val rect = Rect(100,100,200,200)
        canvas.drawRect(rect,mRectPaint)
    }

    private fun findBitmap(): Bitmap {
        var bitmap = BitmapFactory.decodeResource(resources, R.drawable.image)
        val scaleProportion = width * 1f / bitmap.width
        Log.i("findBitmap", "scaleProportion: $scaleProportion")
        val adjustMatrix = Matrix()
        adjustMatrix.setScale(scaleProportion, scaleProportion)
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, adjustMatrix, true)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    private fun drawAxis(canvas: Canvas) {
        val canvasHeight = canvas.height
        var canvasWidth = canvas.width
        testPaint.style = Paint.Style.STROKE
        testPaint.strokeCap = Paint.Cap.ROUND
        testPaint.strokeWidth = 30f

        testPaint.color = Color.GREEN
        canvas.drawLine(0f, 0f, 0f, canvasHeight * 1f, testPaint)


        testPaint.color = Color.BLACK
        canvas.drawLine(0f, 0f, canvasWidth * 1f, 0f, testPaint)

        //平移
        canvas.translate(200f, 200f)
        canvas.drawLine(0f, 0f, canvasWidth * 1f - 200f, 0f, testPaint)
        canvas.drawLine(0f, 0f, 0f, canvasHeight * 1f - 200, testPaint)

        //顺时针旋转30度
        canvas.translate(200f, 200f)
        canvas.rotate(30f)
        canvas.drawLine(0f, 0f, canvasWidth * 1f - 200f, 0f, testPaint)
        canvas.drawLine(0f, 0f, 0f, canvasHeight * 1f - 200, testPaint)
    }

    private fun drawArgb(canvas: Canvas) {
        canvas.drawARGB(255, 139, 197, 186)
    }

    private fun drawText(canvas: Canvas) {
        val canvasWidth = canvas.width
        val canvasHeight = canvas.height
        val translateY = 100f

        mTextPaint.isAntiAlias = true
        mTextPaint.strokeWidth = 6f
        mTextPaint.textSize = 100f


        canvas.translate(0f, translateY)
        canvas.drawText("绘制正常文本", 0f, translateY, mTextPaint)
        canvas.translate(0f, translateY)
        canvas.drawText("绘制正常文本", 0f, translateY, mTextPaint)


        //居中对齐  这是相对于文字中线的
        canvas.translate(0f, translateY + 100)
        mTextPaint.color = Color.BLUE
        mTextPaint.textAlign = Paint.Align.CENTER
        canvas.drawText("居中对齐文本", canvasWidth / 2f, translateY, mTextPaint)

        //左对齐
        canvas.translate(0f, translateY)
        mTextPaint.textAlign = Paint.Align.LEFT
        canvas.drawText("左对齐文本", canvasWidth / 2f, translateY, mTextPaint)

        //右对齐
        canvas.translate(0f, translateY)
        mTextPaint.textAlign = Paint.Align.RIGHT
        canvas.drawText("右对齐文本", canvasWidth / 2f, translateY, mTextPaint)

        //下划线 粗体
        canvas.translate(0f, translateY + 100)
        mTextPaint.textAlign = Paint.Align.CENTER
        mTextPaint.isFakeBoldText = true
        mTextPaint.color = Color.RED
        mTextPaint.isUnderlineText = true
        canvas.drawText("下 划线 粗体 文本", canvasWidth / 2f, translateY, mTextPaint)

        //旋转文本
        canvas.save()
        canvas.translate(0f, translateY + 200)
        canvas.rotate(45f, canvasWidth / 2f, 0f)
        mTextPaint.color = Color.YELLOW
        canvas.drawText("旋转文本", canvasWidth / 2f, translateY, mTextPaint)
        canvas.restore()

        //描边文本
        canvas.translate(0f, translateY + 500)
        mTextPaint.strokeWidth = 5f
        mTextPaint.style = Paint.Style.FILL
        mTextPaint.textSize = 200f
        mTextPaint.textAlign = Paint.Align.LEFT
        mTextPaint.isFakeBoldText = false
        canvas.drawText("描边文本", 0f, translateY, mTextPaint)
        mTextPaint.style = Paint.Style.STROKE
        mTextPaint.color = Color.BLUE
        canvas.drawText("描边文本", 0f, translateY, mTextPaint)

    }

    private fun drawPoint(canvas: Canvas) {
        val canvasHeight = canvas.height
        val canvasWidth = canvas.width
        val translateY = 100f

        mPointPaint.color = Color.GRAY
        //设置线宽，若不设置线宽无法绘制点，线宽决定点的大小
        mPointPaint.strokeWidth = 100f

        //设置无线帽 结果是一个方的点 （和Paint.Cap.SQUARE结果相同）
        mPointPaint.strokeCap = Paint.Cap.BUTT
        canvas.drawPoint(canvasWidth / 2f, translateY, mPointPaint)

        //设置圆形线帽的点 结果是一个圆点
        mPointPaint.strokeCap = Paint.Cap.ROUND
        canvas.translate(0f, 2 * translateY)
        canvas.drawPoint(canvasWidth / 2f, translateY, mPointPaint)
    }

    private fun drawLine(canvas: Canvas) {
        val canvasHeight = canvas.height
        val canvasWidth = canvas.width
        mLinePaint.isAntiAlias = true
        mLinePaint.strokeWidth = 50f
        mLinePaint.strokeCap = Paint.Cap.ROUND
        mLinePaint.color = Color.WHITE

        //画一条直线
        canvas.drawLine(0f, 0f, 500f, 500f, mLinePaint)


        //画多条直线
        canvas.translate(0f, 600f)
        val floatArray = floatArrayOf(0f, 0f, 100f, 100f, 100f, 100f, 0f, 200f)
        canvas.drawLines(floatArray, mLinePaint)
    }

    private fun drawRect(canvas: Canvas) {
        val canvasHeight = canvas.height
        val canvasWidth = canvas.width

        //画矩形
        mRectPaint.color = Color.RED
        canvas.drawRect(10f, 10f, 100f, 100f, mRectPaint)

        //用rect画矩形 还有一个RectF不知道是啥
        mRectPaint.color = Color.GREEN
        canvas.translate(300f, 0f)
        val rect = Rect()
        rect.top = 10
        rect.bottom = 100
        rect.left = 10
        rect.right = 100
        canvas.drawRect(rect, mRectPaint)
    }

    private fun drawCircle(canvas: Canvas) {
        val canvasHeight = canvas.height
        val canvasWidth = canvas.width

        //画一个实心圆
        mCirclePaint.isAntiAlias = true
        mCirclePaint.color = Color.RED
        canvas.drawCircle(100f, 100f, 100f, mCirclePaint)

        //大圆小圆组成圆环
        mCirclePaint.color = Color.GRAY
        canvas.translate(0f, 300f)
        canvas.drawCircle(100f, 100f, 100f, mCirclePaint)
        mCirclePaint.color = Color.GREEN
        canvas.drawCircle(100f, 100f, 50f, mCirclePaint)

        //用线条绘制圆
        canvas.translate(0f, 300f)
        mCirclePaint.style = Paint.Style.STROKE
        mCirclePaint.strokeWidth = 50f
        canvas.drawCircle(100f, 100f, 50f, mCirclePaint)
    }

    private fun drawOval(canvas: Canvas) {
        val canvasHeight = canvas.height
        val canvasWidth = canvas.width
        val translateY = 200f

        val rectF = RectF(50f, 50f, 300f, 150f)
        mOvalPaint.color = Color.BLUE
        mOvalPaint.isAntiAlias = true

        //绘制椭圆轮廓
        mOvalPaint.style = Paint.Style.STROKE //设置画笔为线条模式
        mOvalPaint.strokeWidth = 10f // 设置线条宽度
        canvas.drawOval(rectF, mOvalPaint)

        //绘制椭圆填充面
        canvas.translate(0f, translateY)
        mOvalPaint.style = Paint.Style.FILL
        mOvalPaint.strokeWidth = 10f // 设置线条宽度
        canvas.drawOval(rectF, mOvalPaint)

        //绘制两个椭圆 形成一个带边框的椭圆
        canvas.translate(0f, translateY)
        mOvalPaint.style = Paint.Style.FILL
        canvas.drawOval(rectF, mOvalPaint)
        mOvalPaint.style = Paint.Style.STROKE
        mOvalPaint.color = Color.RED
        canvas.drawOval(rectF, mOvalPaint)
    }

    private fun drawArc(canvas: Canvas) {
        val canvasHeight = canvas.height
        val canvasWidth = canvas.width
        val rectF = RectF(10f, 10f, 500f, 500f)
        val translateY = 300f
        mArcPaint.color = Color.LTGRAY
        mArcPaint.isAntiAlias = true
        mArcPaint.strokeCap = Paint.Cap.ROUND
        mArcPaint.strokeWidth = 20f

        //圆弧
        mArcPaint.style = Paint.Style.STROKE
        canvas.drawArc(rectF, 0f, 90f, false, mArcPaint)

        //uerCenter参数true就是封闭圆心 false相反
        canvas.translate(0f, translateY)
        mArcPaint.style = Paint.Style.FILL
        canvas.drawArc(rectF, 0f, 90f, false, mArcPaint)

        //半弧形
        canvas.translate(0f, translateY)
        canvas.drawArc(rectF, 0f, 90f, true, mArcPaint)

        //带边框的半弧形
        canvas.translate(0f, translateY)
        canvas.drawArc(rectF, 0f, 90f, true, mArcPaint)
        mArcPaint.color = Color.RED
        mArcPaint.style = Paint.Style.STROKE
        canvas.drawArc(rectF, 0f, 90f, true, mArcPaint)
    }

    private fun drawPath(canvas: Canvas) {
        val canvasHeight = canvas.height
        val canvasWidth = canvas.width
        mPathPaint.color = Color.GRAY
        mPathPaint.isAntiAlias = true
        mPathPaint.style = Paint.Style.STROKE
        mPathPaint.strokeWidth = 20f

        val rectF = RectF(0f, 0f, 500f, 500f)
        val rectF2 = RectF(500f, 0f, 1000f, 500f)

        //用path画线条 若将画笔的style设置成fill则是填充效果
        val path = Path()
        path.addArc(rectF, 0f, 90f)
        path.addArc(rectF2, 180f, 90f)
        canvas.drawPath(path, mPathPaint)

        //两个半椭圆交错
        mPathPaint.style = Paint.Style.FILL
        canvas.translate(0f, 300f)
        val path2 = Path()
        path2.addArc(rectF, 0f, 90f)
        path2.addArc(rectF2, 180f, 90f)
        canvas.drawPath(path, mPathPaint)

        //使用lineTo,arcTo,quadTo,cubicTo画线
        canvas.translate(0f, 600f)
        mPathPaint.style = Paint.Style.STROKE
        mPathPaint.strokeWidth = 5f
        val pointList: ArrayList<Point> = ArrayList()
        val path3 = Path()
        path3.moveTo(0f, 0f)
        path3.lineTo(250f, 0f)
        path3.moveTo(250f, 0f)
        val rectF3 = RectF(250f, -125f, 500f, 125f)
        path3.arcTo(rectF3, 180f, 180f)
        path3.moveTo(500f, 0f)

        //二阶贝塞尔曲线
        path3.quadTo(750f, -200f, 1000f, 0f)
        //三阶贝塞尔曲线
        path3.moveTo(1000f, 0f)
        path3.rCubicTo(1200f, 200f, 1350f, 300f, 1500f, 0f)
        canvas.drawPath(path3, mPathPaint)

        pointList.add(Point(0, 0))
        pointList.add(Point(100, 0))
        pointList.add(Point(500, 0))
        pointList.add(Point(750, -200))
        pointList.add(Point(1000, 0))
        pointList.add(Point(1200, 200))
        pointList.add(Point(1350, 300))
        pointList.add(Point(1500, 0))


        mPathPaint.color = Color.RED
        mPathPaint.strokeCap = Paint.Cap.ROUND
        mPathPaint.strokeWidth = 10f
        pointList.forEach { point ->
            canvas.drawPoint(point.x * 1f, point.y * 1f, mPathPaint)
        }
    }

    private fun drawBitmap(canvas: Canvas) {
        mBitmapPaint.isAntiAlias = true
        canvas.drawBitmap(mBitmap, mMatrix, mBitmapPaint)
    }

    private val mRotateDegree = 90f
    private var mRealDegree = 0f

    fun rotateView() {
        val scaleProportion = width * 1f / height * 1f
        val rotateAnimator =
            ObjectAnimator.ofFloat(this, "rotation", mRealDegree, mRealDegree + 90f)
        rotateAnimator.duration = 500
        mRealDegree += 90f
        mRealDegree %= 360f

        val scaleXAnimator: ObjectAnimator = if (mRealDegree == 90f || mRealDegree == 270f) {
            ObjectAnimator.ofFloat(this, "scaleX", 1f, scaleProportion)
        } else {
            ObjectAnimator.ofFloat(this, "scaleX", scaleProportion, 1f)
        }

        val scaleYAnimator: ObjectAnimator = if (mRealDegree == 90f || mRealDegree == 270f) {
            ObjectAnimator.ofFloat(this, "scaleY", 1f, scaleProportion)
        } else {
            ObjectAnimator.ofFloat(this, "scaleY", scaleProportion, 1f)
        }

        scaleYAnimator.duration = 500
        scaleXAnimator.duration = 500

        val animatorSet = AnimatorSet()
        animatorSet.play(scaleXAnimator)
            .with(scaleYAnimator)
            .with(rotateAnimator)

        animatorSet.start()
    }

    fun rotateBitmap() {
        //缩放比例
        val scaleProportion = width * 1f / mBitmap.height

        //旋转动画
        val rotateAnimation = ValueAnimator.ofFloat(mRealDegree, mRealDegree + 90f)
        rotateAnimation.duration = 500
        rotateAnimation.addUpdateListener { animation ->
            mMatrix.setRotate(
                animation?.animatedValue as Float,
                mBitmap.width / 2f,
                mBitmap.height / 2f
            )
            invalidate()
        }

        //缩放动画
        val scaleAnimation = if (mRealDegree == 0f || mRealDegree == 180f) {
            ValueAnimator.ofFloat(1f, scaleProportion)
        } else {
            ValueAnimator.ofFloat(scaleProportion, 1f)
        }

        scaleAnimation.duration = 500
        scaleAnimation.addUpdateListener { animation ->
            mMatrix.postScale(
                animation.animatedValue as Float,
                animation.animatedValue as Float,
                width / 2f,
                height / 2f
            )

        }

        val animatorSet = AnimatorSet()
        animatorSet.play(rotateAnimation)
            .with(scaleAnimation)

        animatorSet.start()
        //记录当前旋转角度
        mRealDegree += 90f
        mRealDegree %= 360f

    }

    fun saveImage() {
        mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.width, mBitmap.height, mMatrix, true)
    }

}